#include "csggrapher.h"
#include<GL/glu.h>
#include "CSG/csgprimitivenode.h"
#include "CSG/bezier.h"

CSGGrapher * grapher;

#ifdef DEBUG
int debug_grapher=1;
#else
int debug_grapher=0;
#endif

int index_ctrl_pts = 0;
int size_of_array = 0;
int step_of_increment = 30;

double ptColor[3][3] = {{0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}};

double * new_point( double x /*= 0.0*/, double y, double z /*= 0.0*/ )
{
    double * pt = new double[3];
    pt[0] = x;
    pt[1] = y;
    pt[2] = z;

    return pt;
}

//double ** initial_pt_array( double * pt )
//{
//    if (pt != NULL)
//    {
//        for (int i = 0; i < size_of_array; i++)
//        {
//            delete []pt_array[i];
//        }
//        delete []pt_array;
//    }

//    index_ctrl_pts = 0;
//    size_of_array = 30;
//    double ** pt_array = new double *[size_of_array];

//    for (int i = 0; i < AXIS_NUM; i++)
//    {
//        pt_array[index_ctrl_pts] = pt;
//    }

//    index_ctrl_pts++;

//    return pt_array;
//}

double ** add_pt_to_array( double ** pt_array, double * pt )
{
    int i = 0;

    if (pt_array != NULL && index_ctrl_pts < size_of_array)
    {
        pt_array[index_ctrl_pts] = pt;
    }
    else
    {
        if (pt_array == NULL)
        {
            size_of_array = 0;
            index_ctrl_pts = 0;
        }

        double ** new_array = new double *[size_of_array + step_of_increment];

        for (i = 0; i < size_of_array; i++)
        {
            new_array[i] = pt_array[i];
        }
        new_array[i] = pt;

        size_of_array += step_of_increment;

        if (pt_array != NULL)
        {
            delete []pt_array;
        }

        pt_array = new_array;
    }

    index_ctrl_pts++;

    return pt_array;
}

void releasePtArray(double **pt_array)
{
    for (int i = 0; i < index_ctrl_pts; i++)
    {
        delete []pt_array[i];
    }
    delete []pt_array;
}

int flag = 1;

Expression exprX()
{
    return CSGPrimitiveNode::expr_x;
}

Expression exprY()
{
    return CSGPrimitiveNode::expr_y;
}

Expression exprZ()
{
    return CSGPrimitiveNode::expr_z;
}

CSGGrapher::CSGGrapher()
{
    csgTree = NULL;

    grid = true;
    dim = 2;

    z0 = 0;
    z1 = 0;
    isoSurf = true;
}

CSGGrapher::~CSGGrapher()
{
    if (csgTree)
    {
        delete csgTree;
    }
}

void CSGGrapher::setCSGTree(Tree<int> * tree)
{
    if (csgTree)
    {
        delete csgTree;
    }
    csgTree = tree;
}

void CSGGrapher::initial()
{
    if (csgTree)
    {
        StarTestBox box(x0, x1, y0, y1, z0, z1);
        ((CSGNode*)csgTree->getRoot())->initial(box, dim);
    }
}

bool CSGGrapher::ptInSet(double *pt)
{
    return ((CSGNode*)csgTree->getRoot())->ptInSet(pt);
}

void CSGGrapher::createCSGTree(CSGNode *root)
{
    if (csgTree)
    {
        delete csgTree;
    }
    csgTree = new Tree<int>(root);
}

void CSGGrapher::drawBoundingBox()
{
    if (csgTree && csgTree->getRoot())
    {
        ((CSGNode*)csgTree->getRoot())->drawBoundingBox();
    }
}

void CSGGrapher::drawCtrlPolygon()
{
    if (csgTree && csgTree->getRoot())
    {
        ((CSGNode*)csgTree->getRoot())->drawControlPolygon();
    }
}

void CSGGrapher::drawContour()
{
    if (csgTree && csgTree->getRoot())
    {
        ((CSGNode*)csgTree->getRoot())->drawContour();
    }
}

void CSGGrapher::drawNaively()
{
    if (csgTree && csgTree->getRoot())
    {
        ((CSGNode*)csgTree->getRoot())->drawNaively();

//        if (grid)
//        {
//            ((CSGNode*)csgTree->getRoot())->drawNaively(grid);
//        }
    }
}

void CSGGrapher::drawCasteljau(int level)
{
    if (csgTree && csgTree->getRoot())
    {
        ((CSGNode*)csgTree->getRoot())->drawCasteljau(level);
    }
}
